package com.hulman.oms.service;

import com.hulman.oms.bean.*;
import com.hulman.oms.dao.MaintainDao;
import com.hulman.oms.dao.MaintainTaskDao;
import com.hulman.oms.dao.MaintainTaskItemDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.JsonUtil;
import com.hulman.oms.util.StringUtil;
import com.hulman.oms.util.SubjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author: maxwellens
 */
@Service
public class MaintainTaskService
{
    private static final String PROCESS_KEY = "maintain";

    private static final String SUB_TAG = "maintain-task";
    @Autowired
    private MaintainTaskDao maintainTaskDao;
    @Autowired
    private MaintainTaskItemDao maintainTaskItemDao;
    @Autowired
    private MaintainDao maintainDao;
    @Autowired
    private UserService userService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private LocationService locationService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private MaintainPlanService maintainPlanService;
    @Autowired
    private TunnelService tunnelService;
    @Autowired
    private MsgService msgService;

    public List<MaintainTask> findMaintainTasks(Map<String, Object> map)
    {
        return maintainTaskDao.findMaintainTasks(map);
    }

    public Integer findMaintainTasksCount(Map<String, Object> map)
    {
        return maintainTaskDao.findMaintainTasksCount(map);
    }

    public Result findMaintainTasksResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = maintainTaskDao.findMaintainTasksCount(map);
        List<MaintainTask> data = maintainTaskDao.findMaintainTasks(map);
        return new Result(data, count);
    }

    public MaintainTask findMaintainTaskById(Integer id)
    {
        return maintainTaskDao.findMaintainTaskById(id);
    }

    public void saveMaintainTask(MaintainTask maintainTask)
    {
        if (maintainTask.getId() != null && maintainTask.getId() != 0)
        {
            maintainTaskDao.updateMaintainTask(maintainTask);
        } else
        {
            maintainTaskDao.insertMaintainTask(maintainTask);
        }
    }

    public void deleteMaintainTaskById(Integer id)
    {
        maintainTaskDao.deleteMaintainTaskById(id);
    }

    public void deleteMaintainTasks(int[] ids)
    {
        maintainTaskDao.deleteMaintainTasks(ids);
    }

    /**
     * 创建专项任务
     *
     * @param maintainTask
     */
    @Transactional(rollbackFor = Exception.class)
    public void create(MaintainTask maintainTask)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        //执行人
        User executeBy = userService.findUserByName(maintainTask.getExecuteByName());
        if (executeBy == null)
        {
            throw new IoTException("不存在人员：" + maintainTask.getExecuteByName());
        }
        maintainTask.setExecuteById(executeBy.getId());
        maintainTask.setCreateTime(new Date());
        maintainTask.setState(MaintainTask.STATE_EXECUTING);
        //创建专项任务
        maintainTaskDao.insertMaintainTask(maintainTask);
        //拆分专项任务子项
        List<MaintainTaskItem> maintainTaskItems = splitMaintainTaskToItems(maintainTask);
        for (MaintainTaskItem maintainTaskItem : maintainTaskItems)
        {
            maintainTaskItemDao.insertMaintainTaskItem(maintainTaskItem);
        }
        //创建并完成任务
        Task task1 = new Task();
        Maintain maintain = maintainDao.findMaintainById(maintainTask.getMaintainId());
        task1.setProcInstId(maintain.getProcInstId());
        task1.setOwnerId(user.getId());
        task1.setOwnerName(user.getName());
        task1.setName("创建专项任务");
        task1.setTag(PROCESS_KEY);
        task1.setSubTag(SUB_TAG);
        task1.addExtra("专项单号", maintain.getNo());
        task1.addExtra("保养名称", maintainTask.getName());
        task1.addExtra("保养单元", maintainTask.getUnitName());
        task1.addExtra("保养对象", maintainTask.getObject());
        taskService.createAndCompleteTask(task1);
        //生成任务
        Task task2 = new Task();
        task2.setProcInstId(maintain.getProcInstId());
        task2.setOwnerId(executeBy.getId());
        task2.setOwnerName(executeBy.getName());
        task2.setName("完成专项任务");
        task2.setTag(PROCESS_KEY);
        task2.setSubTag(SUB_TAG);
        task2.setFormKey(maintainTask.getId().toString());
        task2.addExtra("专项单号", maintain.getNo());
        task2.addExtra("保养名称", maintainTask.getName());
        task2.addExtra("保养单元", maintainTask.getUnitName());
        task2.addExtra("保养对象", maintainTask.getObject());
        taskService.addTask(task2);
        task2.setPath("/pages/maintain/task?taskId=" + task2.getId());
        task2.setPage("/maintain-task.html?taskId=" + task2.getId());
        taskService.saveTask(task2);
        msgService.sendMsg(task2.toMsg());
        //通知相关人
        String notifyNames = maintainTask.getNotifyNames();
        if (! StringUtil.isEmpty(notifyNames))
        {
            String[] notifyUserNames = notifyNames.split(",");
            for (String notifyName : notifyUserNames)
            {
                User notifyUser = userService.findUserByName(notifyName);
                if (notifyUser != null)
                {
                    Msg msg = new Msg();
                    msg.setTitle("新的专项任务");
                    msg.addItem("专项名称", maintainTask.getName());
                    msg.addItem("保养单元", maintainTask.getUnitName());
                    msg.addItem("保养对象", maintainTask.getObject());
                    msg.setType(Msg.TYPE_OM);
                    msg.setPath("/pages/maintain/task?id=" + maintainTask.getId());
                    msg.setCreateTime(new Date());
                    msg.setState(Msg.STATE_UNREAD);
                    msg.setOwnerId(notifyUser.getId());
                    msg.setOwnerName(notifyUser.getName());
                    msgService.sendMsg(msg);
                }
            }
        }
    }

    /**
     * 把专项任务拆分为任务子项
     *
     * @param maintainTask
     * @return
     */
    private List<MaintainTaskItem> splitMaintainTaskToItems(MaintainTask maintainTask)
    {
        List<MaintainTaskItem> list = new ArrayList<>();
        if (maintainTask.getUnit() == MaintainPlan.UNIT_TUNNEL)
        {
            String[] tunnels = maintainTask.getTunnels().split(",");
            for (String tunnel : tunnels)
            {
                MaintainTaskItem item = new MaintainTaskItem();
                item.setMaintainTaskId(maintainTask.getId());
                item.setUnit(maintainTask.getUnit());
                item.setTunnel(tunnel);
                list.add(item);
            }
        } else if (maintainTask.getUnit() == MaintainPlan.UNIT_AREA)
        {
            String[] areas = maintainTask.getAreas().split(",");
            for (String area : areas)
            {
                Location location = locationService.findLocationByName(area);
                MaintainTaskItem item = new MaintainTaskItem();
                item.setMaintainTaskId(maintainTask.getId());
                item.setUnit(maintainTask.getUnit());
                if (location != null)
                {
                    item.setTunnel(location.getTunnelName());
                }
                item.setArea(area);
                list.add(item);
            }
        } else if (maintainTask.getUnit() == MaintainPlan.UNIT_DEVICE)
        {
            Map<String, Object> condition = new HashMap<>();
            String deviceSystem = maintainTask.getDeviceSystem();
            condition.put("system", deviceSystem);
            String tunnelIds = tunnelService.parseTunnelIds(maintainTask.getTunnels());
            condition.put("tunnelIds", tunnelIds.split(","));
            List<Device> devices = deviceService.findDevices(condition);
            for (Device device : devices)
            {
                MaintainTaskItem item = new MaintainTaskItem();
                item.setMaintainTaskId(maintainTask.getId());
                item.setUnit(maintainTask.getUnit());
                item.setTunnel(device.getTunnelName());
                item.setDeviceSystem(deviceSystem);
                item.setDeviceCode(device.getCode());
                item.setDeviceName(device.getName());
                list.add(item);
            }
        }
        Maintain maintain = maintainDao.findMaintainById(maintainTask.getMaintainId());
        List<MaintainContentItem> content = maintainPlanService.generateMaintainContent(maintain.getMaintainPlanId());
        for (MaintainTaskItem item : list)
        {
            item.setContent(JsonUtil.toJSONString(content));
            item.setAuditTimes(0);
            item.setState(MaintainTaskItem.STATE_CREATED);
        }
        return list;
    }

    /**
     * 完成专项任务
     *
     * @param maintainTaskId
     * @param vehicle
     * @param driver
     */
    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer taskId, Integer maintainTaskId, String vehicle, String driver)
    {
        MaintainTask maintainTask = maintainTaskDao.findMaintainTaskById(maintainTaskId);
        maintainTask.setVehicle(vehicle);
        maintainTask.setDriver(driver);
        maintainTask.setCompleteTime(new Date());
        maintainTask.setState(MaintainTask.STATE_EXECUTED);
        maintainTaskDao.updateMaintainTask(maintainTask);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
        //通知负责人已完成
        Maintain maintain = maintainDao.findMaintainById(maintainTask.getMaintainId());
        Msg msg = new Msg();
        msg.setTitle("专项任务已完成");
        msg.addItem("专项名称", maintainTask.getName());
        msg.addItem("保养单元", maintainTask.getUnitName());
        msg.addItem("保养对象", maintainTask.getObject());
        msg.setType(Msg.TYPE_OM);
        msg.setCreateTime(new Date());
        msg.setState(Msg.STATE_UNREAD);
        msg.setOwnerId(maintain.getDirectorId());
        msg.setOwnerName(maintain.getDirectorName());
        msgService.sendMsg(msg);
    }

    @Transactional(rollbackFor = Exception.class)
    public void cancel(Integer id)
    {
        //删除任务项
        MaintainTask maintainTask = maintainTaskDao.findMaintainTaskById(id);
        maintainTaskDao.deleteMaintainTaskById(id);
        //删除关联任务
        Map<String, Object> map = new HashMap<>();
        map.put("subTag", SUB_TAG);
        map.put("name", "完成专项任务");
        map.put("formKey", maintainTask.getId().toString());
        List<Task> tasks = taskService.findTasks(map);
        for (Task task : tasks)
        {
            taskService.deleteTaskById(task.getId());
        }
    }

    public List<NameValue> statDailyMaintainTasks(Integer days)
    {
        return maintainTaskDao.statDailyMaintainTasks(days);
    }
}
